home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 242 / Issue 242 - April 2008 - DPCS0408DVD.ISO / Software Money Savers / VirtualDub / Source / VirtualDub-1.7.7-src.7z / src / Asuka / source / fxc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2007-07-22  |  45.0 KB  |  1,134 lines

  1. //    Asuka - VirtualDub Build/Post-Mortem Utility
  2. //    Copyright (C) 2005 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #include "stdafx.h"
  19. #include <vector>
  20. #include <list>
  21. #include <string>
  22. #include <d3d9.h>
  23. #include <d3dx9.h>
  24. #include <objbase.h>
  25. #include <vd2/system/refcount.h>
  26. #include <vd2/system/filesys.h>
  27. #include <vd2/system/math.h>
  28. #include <vd2/system/vdstl.h>
  29.  
  30. #pragma comment(lib, "d3dx9")
  31.  
  32. #define NOT_IMPLEMENTED() puts(__FUNCTION__); return E_NOTIMPL
  33. #define NOT_IMPLEMENTED_VOID()
  34.  
  35. namespace
  36. {
  37.     static const char *const kTextureNames[]={
  38.         "vd_srctexture",
  39.         "vd_src2atexture",
  40.         "vd_src2btexture",
  41.         "vd_temptexture",
  42.         "vd_temp2texture",
  43.         "vd_cubictexture",
  44.         "vd_hevenoddtexture",
  45.         "vd_interphtexture",
  46.         "vd_interpvtexture"
  47.     };
  48.  
  49.     static const char *const kParameterNames[]={
  50.         "vd_vpsize",
  51.         "vd_cvpsize",
  52.         "vd_texsize",
  53.         "vd_tex2size",
  54.         "vd_srcsize",
  55.         "vd_tempsize",
  56.         "vd_temp2size",
  57.         "vd_vpcorrect",
  58.         "vd_vpcorrect2",
  59.         "vd_tvpcorrect",
  60.         "vd_tvpcorrect2",
  61.         "vd_t2vpcorrect",
  62.         "vd_t2vpcorrect2",
  63.         "vd_time",
  64.         "vd_interphtexsize",
  65.         "vd_interpvtexsize",
  66.     };
  67. }
  68.  
  69. namespace
  70. {
  71.     class DummyD3DVertexShader : public IDirect3DVertexShader9 {
  72.     public:
  73.         DummyD3DVertexShader(IDirect3DDevice9 *pDevice, const DWORD *pByteCode) : mRefCount(0), mpDevice(pDevice), mByteCode(pByteCode, pByteCode + (D3DXGetShaderSize(pByteCode) >> 2)) {}
  74.  
  75.         /*** IUnknown methods ***/
  76.         HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObj) {
  77.             if (riid == IID_IDirect3DVertexShader9)
  78.                 *ppvObj = static_cast<IDirect3DVertexShader9 *>(this);
  79.             else if (riid == IID_IUnknown)
  80.                 *ppvObj = static_cast<IUnknown *>(this);
  81.             else {
  82.                 *ppvObj = NULL;
  83.                 return E_NOINTERFACE;
  84.             }
  85.  
  86.             AddRef();
  87.             return S_OK;
  88.         }
  89.  
  90.         ULONG    STDMETHODCALLTYPE AddRef() {
  91.             return (ULONG)InterlockedIncrement(&mRefCount);
  92.         }
  93.         ULONG    STDMETHODCALLTYPE Release() {
  94.             ULONG rv = (ULONG)InterlockedDecrement(&mRefCount);
  95.             if (!rv)
  96.                 delete this;
  97.             return rv;
  98.         }
  99.  
  100.         /*** IDirect3DVertexShader9 methods ***/
  101.         HRESULT STDMETHODCALLTYPE GetDevice(IDirect3DDevice9** ppDevice) {
  102.             *ppDevice = mpDevice;
  103.             (*ppDevice)->AddRef();
  104.             return S_OK;
  105.         }
  106.  
  107.         HRESULT STDMETHODCALLTYPE GetFunction(void* p, UINT* pSizeOfData) {
  108.             UINT bytes = (UINT)(mByteCode.size() << 2);
  109.  
  110.             if (!p)
  111.                 *pSizeOfData = bytes;
  112.             else if (*pSizeOfData < bytes)
  113.                 return D3DERR_INVALIDCALL;
  114.             else {
  115.                 *pSizeOfData = bytes;
  116.                 memcpy(p, &mByteCode[0], bytes);
  117.             }
  118.  
  119.             return S_OK;
  120.         }
  121.  
  122.     protected:
  123.         volatile LONG mRefCount;
  124.         vdrefptr<IDirect3DDevice9> mpDevice;
  125.         std::vector<DWORD> mByteCode;
  126.     };
  127.  
  128.     class DummyD3DPixelShader : public IDirect3DPixelShader9 {
  129.     public:
  130.         DummyD3DPixelShader(IDirect3DDevice9 *pDevice, const DWORD *pByteCode) : mRefCount(0), mpDevice(pDevice), mByteCode(pByteCode, pByteCode + (D3DXGetShaderSize(pByteCode) >> 2)) {}
  131.  
  132.         /*** IUnknown methods ***/
  133.         HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObj) {
  134.             if (riid == IID_IDirect3DPixelShader9)
  135.                 *ppvObj = static_cast<IDirect3DPixelShader9 *>(this);
  136.             else if (riid == IID_IUnknown)
  137.                 *ppvObj = static_cast<IUnknown *>(this);
  138.             else {
  139.                 *ppvObj = NULL;
  140.                 return E_NOINTERFACE;
  141.             }
  142.  
  143.             AddRef();
  144.             return S_OK;
  145.         }
  146.  
  147.         ULONG    STDMETHODCALLTYPE AddRef() {
  148.             return (ULONG)InterlockedIncrement(&mRefCount);
  149.         }
  150.         ULONG    STDMETHODCALLTYPE Release() {
  151.             ULONG rv = (ULONG)InterlockedDecrement(&mRefCount);
  152.             if (!rv)
  153.                 delete this;
  154.             return rv;
  155.         }
  156.  
  157.         /*** IDirect3DPixelShader9 methods ***/
  158.         HRESULT STDMETHODCALLTYPE GetDevice(IDirect3DDevice9** ppDevice) {
  159.             *ppDevice = mpDevice;
  160.             (*ppDevice)->AddRef();
  161.             return S_OK;
  162.         }
  163.  
  164.         HRESULT STDMETHODCALLTYPE GetFunction(void* p, UINT* pSizeOfData) {
  165.             UINT bytes = (UINT)(mByteCode.size() << 2);
  166.  
  167.             if (!p)
  168.                 *pSizeOfData = bytes;
  169.             else if (*pSizeOfData < bytes)
  170.                 return D3DERR_INVALIDCALL;
  171.             else {
  172.                 *pSizeOfData = bytes;
  173.                 memcpy(p, &mByteCode[0], bytes);
  174.             }
  175.  
  176.             return S_OK;
  177.         }
  178.  
  179.     protected:
  180.         volatile LONG mRefCount;
  181.         vdrefptr<IDirect3DDevice9> mpDevice;
  182.         std::vector<DWORD> mByteCode;
  183.     };
  184.  
  185.     class DummyD3DBaseTexture : public IDirect3DBaseTexture9
  186.     {
  187.     public:
  188.         DummyD3DBaseTexture(IDirect3DDevice9 *pDevice, uint32 id) : mRefCount(0), mpDevice(pDevice), mId(id) {}
  189.  
  190.         /*** IUnknown methods ***/
  191.         HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObj) {
  192.             if (riid == IID_IDirect3DBaseTexture9)
  193.                 *ppvObj = static_cast<IDirect3DBaseTexture9 *>(this);
  194.             else if (riid == IID_IDirect3DResource9)
  195.                 *ppvObj = static_cast<IDirect3DResource9 *>(this);
  196.             else if (riid == IID_IUnknown)
  197.                 *ppvObj = static_cast<IUnknown *>(this);
  198.             else {
  199.                 *ppvObj = NULL;
  200.                 return E_NOINTERFACE;
  201.             }
  202.  
  203.             AddRef();
  204.             return S_OK;
  205.         }
  206.  
  207.         ULONG    STDMETHODCALLTYPE AddRef() {
  208.             return (ULONG)InterlockedIncrement(&mRefCount);
  209.         }
  210.         ULONG    STDMETHODCALLTYPE Release() {
  211.             ULONG rv = (ULONG)InterlockedDecrement(&mRefCount);
  212.             if (!rv)
  213.                 delete this;
  214.             return rv;
  215.         }
  216.  
  217.         /*** IDirect3DResource9 methods ***/
  218.         HRESULT STDMETHODCALLTYPE GetDevice(IDirect3DDevice9** ppDevice) {
  219.             *ppDevice = mpDevice;
  220.             (*ppDevice)->AddRef();
  221.             return S_OK;
  222.         }
  223.  
  224.         HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) { NOT_IMPLEMENTED(); }
  225.         HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID refguid,void* pData,DWORD* pSizeOfData) { NOT_IMPLEMENTED(); }
  226.         HRESULT STDMETHODCALLTYPE FreePrivateData(REFGUID refguid) { NOT_IMPLEMENTED(); }
  227.         DWORD    STDMETHODCALLTYPE SetPriority(DWORD PriorityNew) { NOT_IMPLEMENTED_VOID(); return 0; }
  228.         DWORD    STDMETHODCALLTYPE GetPriority() { return 0; }
  229.         void    STDMETHODCALLTYPE PreLoad() {}
  230.         D3DRESOURCETYPE STDMETHODCALLTYPE GetType() {
  231.             return D3DRTYPE_TEXTURE;
  232.         }
  233.         DWORD    STDMETHODCALLTYPE SetLOD(DWORD LODNew) { NOT_IMPLEMENTED_VOID(); return 0; }
  234.         DWORD    STDMETHODCALLTYPE GetLOD() { return 0; }
  235.         DWORD    STDMETHODCALLTYPE GetLevelCount() { return 1; }
  236.         HRESULT STDMETHODCALLTYPE SetAutoGenFilterType(D3DTEXTUREFILTERTYPE FilterType) { NOT_IMPLEMENTED(); }
  237.         D3DTEXTUREFILTERTYPE STDMETHODCALLTYPE GetAutoGenFilterType() {
  238.             return D3DTEXF_LINEAR;
  239.         }
  240.         void    STDMETHODCALLTYPE GenerateMipSubLevels() {}
  241.  
  242.     public:
  243.         uint32 GetId() const { return mId; }
  244.  
  245.     protected:
  246.         volatile LONG mRefCount;
  247.         vdrefptr<IDirect3DDevice9> mpDevice;
  248.         uint32 mId;
  249.     };
  250.  
  251.     class DummyD3DDevice : public IDirect3DDevice9 {
  252.     public:
  253.         DummyD3DDevice() : mRefCount(0) {}
  254.  
  255.         /*** IUnknown methods ***/
  256.         HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObj) {
  257.             if (riid == IID_IDirect3DDevice9)
  258.                 *ppvObj = static_cast<IDirect3DDevice9 *>(this);
  259.             else if (riid == IID_IUnknown)
  260.                 *ppvObj = static_cast<IUnknown *>(this);
  261.             else {
  262.                 *ppvObj = NULL;
  263.                 return E_NOINTERFACE;
  264.             }
  265.  
  266.             AddRef();
  267.             return S_OK;
  268.         }
  269.  
  270.         ULONG    STDMETHODCALLTYPE AddRef() {
  271.             return (ULONG)InterlockedIncrement(&mRefCount);
  272.         }
  273.         ULONG    STDMETHODCALLTYPE Release() {
  274.             ULONG rv = (ULONG)InterlockedDecrement(&mRefCount);
  275.             if (!rv)
  276.                 delete this;
  277.             return rv;
  278.         }
  279.  
  280.         /*** IDirect3DDevice9 methods ***/
  281.         HRESULT STDMETHODCALLTYPE TestCooperativeLevel() { NOT_IMPLEMENTED(); }
  282.         UINT    STDMETHODCALLTYPE GetAvailableTextureMem() { return 16777216; }
  283.         HRESULT STDMETHODCALLTYPE EvictManagedResources() { NOT_IMPLEMENTED(); }
  284.         HRESULT STDMETHODCALLTYPE GetDirect3D(IDirect3D9** ppD3D9) { NOT_IMPLEMENTED(); }
  285.         HRESULT STDMETHODCALLTYPE GetDeviceCaps(D3DCAPS9* pCaps) { NOT_IMPLEMENTED(); }
  286.         HRESULT STDMETHODCALLTYPE GetDisplayMode(UINT iSwapChain,D3DDISPLAYMODE* pMode) { NOT_IMPLEMENTED(); }
  287.         HRESULT STDMETHODCALLTYPE GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS *pParameters) { NOT_IMPLEMENTED(); }
  288.         HRESULT STDMETHODCALLTYPE SetCursorProperties(UINT XHotSpot,UINT YHotSpot,IDirect3DSurface9* pCursorBitmap) { NOT_IMPLEMENTED(); }
  289.         void    STDMETHODCALLTYPE SetCursorPosition(int X,int Y,DWORD Flags) {}
  290.         BOOL    STDMETHODCALLTYPE ShowCursor(BOOL bShow) { return TRUE; }
  291.         HRESULT STDMETHODCALLTYPE CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DSwapChain9** pSwapChain) { NOT_IMPLEMENTED(); }
  292.         HRESULT STDMETHODCALLTYPE GetSwapChain(UINT iSwapChain,IDirect3DSwapChain9** pSwapChain) { NOT_IMPLEMENTED(); }
  293.         UINT    STDMETHODCALLTYPE GetNumberOfSwapChains() { return 1; }
  294.         HRESULT STDMETHODCALLTYPE Reset(D3DPRESENT_PARAMETERS* pPresentationParameters) { NOT_IMPLEMENTED(); }
  295.         HRESULT STDMETHODCALLTYPE Present(CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) { NOT_IMPLEMENTED(); }
  296.         HRESULT STDMETHODCALLTYPE GetBackBuffer(UINT iSwapChain,UINT iBackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface9** ppBackBuffer) { NOT_IMPLEMENTED(); }
  297.         HRESULT STDMETHODCALLTYPE GetRasterStatus(UINT iSwapChain,D3DRASTER_STATUS* pRasterStatus) { NOT_IMPLEMENTED(); }
  298.         HRESULT STDMETHODCALLTYPE SetDialogBoxMode(BOOL bEnableDialogs) { NOT_IMPLEMENTED(); }
  299.         void    STDMETHODCALLTYPE SetGammaRamp(UINT iSwapChain,DWORD Flags,CONST D3DGAMMARAMP* pRamp) { }
  300.         void    STDMETHODCALLTYPE GetGammaRamp(UINT iSwapChain,D3DGAMMARAMP* pRamp) { NOT_IMPLEMENTED_VOID(); }
  301.         HRESULT STDMETHODCALLTYPE CreateTexture(UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture9** ppTexture,HANDLE* pSharedHandle) { NOT_IMPLEMENTED(); }
  302.         HRESULT STDMETHODCALLTYPE CreateVolumeTexture(UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture9** ppVolumeTexture,HANDLE* pSharedHandle) { NOT_IMPLEMENTED(); }
  303.         HRESULT STDMETHODCALLTYPE CreateCubeTexture(UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture9** ppCubeTexture,HANDLE* pSharedHandle) { NOT_IMPLEMENTED(); }
  304.         HRESULT STDMETHODCALLTYPE CreateVertexBuffer(UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer9** ppVertexBuffer,HANDLE* pSharedHandle) { NOT_IMPLEMENTED(); }
  305.         HRESULT STDMETHODCALLTYPE CreateIndexBuffer(UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer9** ppIndexBuffer,HANDLE* pSharedHandle) { NOT_IMPLEMENTED(); }
  306.         HRESULT STDMETHODCALLTYPE CreateRenderTarget(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Lockable,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) { NOT_IMPLEMENTED(); }
  307.         HRESULT STDMETHODCALLTYPE CreateDepthStencilSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Discard,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) { NOT_IMPLEMENTED(); }
  308.         HRESULT STDMETHODCALLTYPE UpdateSurface(IDirect3DSurface9* pSourceSurface,CONST RECT* pSourceRect,IDirect3DSurface9* pDestinationSurface,CONST POINT* pDestPoint) { NOT_IMPLEMENTED(); }
  309.         HRESULT STDMETHODCALLTYPE UpdateTexture(IDirect3DBaseTexture9* pSourceTexture,IDirect3DBaseTexture9* pDestinationTexture) { NOT_IMPLEMENTED(); }
  310.         HRESULT STDMETHODCALLTYPE GetRenderTargetData(IDirect3DSurface9* pRenderTarget,IDirect3DSurface9* pDestSurface) { NOT_IMPLEMENTED(); }
  311.         HRESULT STDMETHODCALLTYPE GetFrontBufferData(UINT iSwapChain,IDirect3DSurface9* pDestSurface) { NOT_IMPLEMENTED(); }
  312.         HRESULT STDMETHODCALLTYPE StretchRect(IDirect3DSurface9* pSourceSurface,CONST RECT* pSourceRect,IDirect3DSurface9* pDestSurface,CONST RECT* pDestRect,D3DTEXTUREFILTERTYPE Filter) { NOT_IMPLEMENTED(); }
  313.         HRESULT STDMETHODCALLTYPE ColorFill(IDirect3DSurface9* pSurface,CONST RECT* pRect,D3DCOLOR color) { NOT_IMPLEMENTED(); }
  314.         HRESULT STDMETHODCALLTYPE CreateOffscreenPlainSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DPOOL Pool,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) { NOT_IMPLEMENTED(); }
  315.         HRESULT STDMETHODCALLTYPE SetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9* pRenderTarget) { NOT_IMPLEMENTED(); }
  316.         HRESULT STDMETHODCALLTYPE GetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9** ppRenderTarget) { NOT_IMPLEMENTED(); }
  317.         HRESULT STDMETHODCALLTYPE SetDepthStencilSurface(IDirect3DSurface9* pNewZStencil) { NOT_IMPLEMENTED(); }
  318.         HRESULT STDMETHODCALLTYPE GetDepthStencilSurface(IDirect3DSurface9** ppZStencilSurface) { NOT_IMPLEMENTED(); }
  319.         HRESULT STDMETHODCALLTYPE BeginScene() { NOT_IMPLEMENTED(); }
  320.         HRESULT STDMETHODCALLTYPE EndScene() { NOT_IMPLEMENTED(); }
  321.         HRESULT STDMETHODCALLTYPE Clear(DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) { NOT_IMPLEMENTED(); }
  322.         HRESULT STDMETHODCALLTYPE SetTransform(D3DTRANSFORMSTATETYPE State,CONST D3DMATRIX* pMatrix) { NOT_IMPLEMENTED(); }
  323.         HRESULT STDMETHODCALLTYPE GetTransform(D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) { NOT_IMPLEMENTED(); }
  324.         HRESULT STDMETHODCALLTYPE MultiplyTransform(D3DTRANSFORMSTATETYPE,CONST D3DMATRIX*) { NOT_IMPLEMENTED(); }
  325.         HRESULT STDMETHODCALLTYPE SetViewport(CONST D3DVIEWPORT9* pViewport) { NOT_IMPLEMENTED(); }
  326.         HRESULT STDMETHODCALLTYPE GetViewport(D3DVIEWPORT9* pViewport) { NOT_IMPLEMENTED(); }
  327.         HRESULT STDMETHODCALLTYPE SetMaterial(CONST D3DMATERIAL9* pMaterial) { NOT_IMPLEMENTED(); }
  328.         HRESULT STDMETHODCALLTYPE GetMaterial(D3DMATERIAL9* pMaterial) { NOT_IMPLEMENTED(); }
  329.         HRESULT STDMETHODCALLTYPE SetLight(DWORD Index,CONST D3DLIGHT9*) { NOT_IMPLEMENTED(); }
  330.         HRESULT STDMETHODCALLTYPE GetLight(DWORD Index,D3DLIGHT9*) { NOT_IMPLEMENTED(); }
  331.         HRESULT STDMETHODCALLTYPE LightEnable(DWORD Index,BOOL Enable) { NOT_IMPLEMENTED(); }
  332.         HRESULT STDMETHODCALLTYPE GetLightEnable(DWORD Index,BOOL* pEnable) { NOT_IMPLEMENTED(); }
  333.         HRESULT STDMETHODCALLTYPE SetClipPlane(DWORD Index,CONST float* pPlane) { NOT_IMPLEMENTED(); }
  334.         HRESULT STDMETHODCALLTYPE GetClipPlane(DWORD Index,float* pPlane) { NOT_IMPLEMENTED(); }
  335.         HRESULT STDMETHODCALLTYPE GetRenderState(D3DRENDERSTATETYPE State,DWORD* pValue) { NOT_IMPLEMENTED(); }
  336.         HRESULT STDMETHODCALLTYPE CreateStateBlock(D3DSTATEBLOCKTYPE Type,IDirect3DStateBlock9** ppSB) { NOT_IMPLEMENTED(); }
  337.         HRESULT STDMETHODCALLTYPE BeginStateBlock() { NOT_IMPLEMENTED(); }
  338.         HRESULT STDMETHODCALLTYPE EndStateBlock(IDirect3DStateBlock9** ppSB) { NOT_IMPLEMENTED(); }
  339.         HRESULT STDMETHODCALLTYPE SetClipStatus(CONST D3DCLIPSTATUS9* pClipStatus) { NOT_IMPLEMENTED(); }
  340.         HRESULT STDMETHODCALLTYPE GetClipStatus(D3DCLIPSTATUS9* pClipStatus) { NOT_IMPLEMENTED(); }
  341.         HRESULT STDMETHODCALLTYPE GetTexture(DWORD Stage,IDirect3DBaseTexture9** ppTexture) { NOT_IMPLEMENTED(); }
  342.         HRESULT STDMETHODCALLTYPE GetTextureStageState(DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) { NOT_IMPLEMENTED(); }
  343.         HRESULT STDMETHODCALLTYPE GetSamplerState(DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD* pValue) { NOT_IMPLEMENTED(); }
  344.         HRESULT STDMETHODCALLTYPE ValidateDevice(DWORD* pNumPasses) { NOT_IMPLEMENTED(); }
  345.         HRESULT STDMETHODCALLTYPE SetPaletteEntries(UINT PaletteNumber,CONST PALETTEENTRY* pEntries) { NOT_IMPLEMENTED(); }
  346.         HRESULT STDMETHODCALLTYPE GetPaletteEntries(UINT PaletteNumber,PALETTEENTRY* pEntries) { NOT_IMPLEMENTED(); }
  347.         HRESULT STDMETHODCALLTYPE SetCurrentTexturePalette(UINT PaletteNumber) { NOT_IMPLEMENTED(); }
  348.         HRESULT STDMETHODCALLTYPE GetCurrentTexturePalette(UINT *PaletteNumber) { NOT_IMPLEMENTED(); }
  349.         HRESULT STDMETHODCALLTYPE SetScissorRect(CONST RECT* pRect) { NOT_IMPLEMENTED(); }
  350.         HRESULT STDMETHODCALLTYPE GetScissorRect(RECT* pRect) { NOT_IMPLEMENTED(); }
  351.         HRESULT STDMETHODCALLTYPE SetSoftwareVertexProcessing(BOOL bSoftware) { NOT_IMPLEMENTED(); }
  352.         BOOL    STDMETHODCALLTYPE GetSoftwareVertexProcessing() { return FALSE; }
  353.         HRESULT STDMETHODCALLTYPE SetNPatchMode(float nSegments) { NOT_IMPLEMENTED(); }
  354.         float    STDMETHODCALLTYPE GetNPatchMode() { return 0; }
  355.         HRESULT STDMETHODCALLTYPE DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) { NOT_IMPLEMENTED(); }
  356.         HRESULT STDMETHODCALLTYPE DrawIndexedPrimitive(D3DPRIMITIVETYPE,INT BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount) { NOT_IMPLEMENTED(); }
  357.         HRESULT STDMETHODCALLTYPE DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) { NOT_IMPLEMENTED(); }
  358.         HRESULT STDMETHODCALLTYPE DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertices,UINT PrimitiveCount,CONST void* pIndexData,D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) { NOT_IMPLEMENTED(); }
  359.         HRESULT STDMETHODCALLTYPE ProcessVertices(UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer9* pDestBuffer,IDirect3DVertexDeclaration9* pVertexDecl,DWORD Flags) { NOT_IMPLEMENTED(); }
  360.         HRESULT STDMETHODCALLTYPE CreateVertexDeclaration(CONST D3DVERTEXELEMENT9* pVertexElements,IDirect3DVertexDeclaration9** ppDecl) { NOT_IMPLEMENTED(); }
  361.         HRESULT STDMETHODCALLTYPE SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl) { NOT_IMPLEMENTED(); }
  362.         HRESULT STDMETHODCALLTYPE GetVertexDeclaration(IDirect3DVertexDeclaration9** ppDecl) { NOT_IMPLEMENTED(); }
  363.         HRESULT STDMETHODCALLTYPE SetFVF(DWORD FVF) { NOT_IMPLEMENTED(); }
  364.         HRESULT STDMETHODCALLTYPE GetFVF(DWORD* pFVF) { NOT_IMPLEMENTED(); }
  365.         HRESULT STDMETHODCALLTYPE GetVertexShader(IDirect3DVertexShader9** ppShader) { NOT_IMPLEMENTED(); }
  366.         HRESULT STDMETHODCALLTYPE GetVertexShaderConstantF(UINT StartRegister,float* pConstantData,UINT Vector4fCount) { NOT_IMPLEMENTED(); }
  367.         HRESULT STDMETHODCALLTYPE GetVertexShaderConstantI(UINT StartRegister,int* pConstantData,UINT Vector4iCount) { NOT_IMPLEMENTED(); }
  368.         HRESULT STDMETHODCALLTYPE GetVertexShaderConstantB(UINT StartRegister,BOOL* pConstantData,UINT BoolCount) { NOT_IMPLEMENTED(); }
  369.         HRESULT STDMETHODCALLTYPE SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride) { NOT_IMPLEMENTED(); }
  370.         HRESULT STDMETHODCALLTYPE GetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9** ppStreamData,UINT* pOffsetInBytes,UINT* pStride) { NOT_IMPLEMENTED(); }
  371.         HRESULT STDMETHODCALLTYPE SetStreamSourceFreq(UINT StreamNumber,UINT Setting) { NOT_IMPLEMENTED(); }
  372.         HRESULT STDMETHODCALLTYPE GetStreamSourceFreq(UINT StreamNumber,UINT* pSetting) { NOT_IMPLEMENTED(); }
  373.         HRESULT STDMETHODCALLTYPE SetIndices(IDirect3DIndexBuffer9* pIndexData) { NOT_IMPLEMENTED(); }
  374.         HRESULT STDMETHODCALLTYPE GetIndices(IDirect3DIndexBuffer9** ppIndexData) { NOT_IMPLEMENTED(); }
  375.         HRESULT STDMETHODCALLTYPE GetPixelShader(IDirect3DPixelShader9** ppShader) { NOT_IMPLEMENTED(); }
  376.         HRESULT STDMETHODCALLTYPE GetPixelShaderConstantI(UINT StartRegister,int* pConstantData,UINT Vector4iCount) { NOT_IMPLEMENTED(); }
  377.         HRESULT STDMETHODCALLTYPE GetPixelShaderConstantF(UINT StartRegister,float* pConstantData,UINT Vector4fCount) { NOT_IMPLEMENTED(); }
  378.         HRESULT STDMETHODCALLTYPE GetPixelShaderConstantB(UINT StartRegister,BOOL* pConstantData,UINT BoolCount) { NOT_IMPLEMENTED(); }
  379.         HRESULT STDMETHODCALLTYPE DrawRectPatch(UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) { NOT_IMPLEMENTED(); }
  380.         HRESULT STDMETHODCALLTYPE DrawTriPatch(UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) { NOT_IMPLEMENTED(); }
  381.         HRESULT STDMETHODCALLTYPE DeletePatch(UINT Handle) { NOT_IMPLEMENTED(); }
  382.         HRESULT STDMETHODCALLTYPE CreateQuery(D3DQUERYTYPE Type,IDirect3DQuery9** ppQuery) { NOT_IMPLEMENTED(); }
  383.  
  384.         HRESULT STDMETHODCALLTYPE CreateVertexShader(CONST DWORD* pFunction,IDirect3DVertexShader9** ppShader) {
  385.             *ppShader = new DummyD3DVertexShader(this, pFunction);
  386.             (*ppShader)->AddRef();
  387.             return S_OK;
  388.         }
  389.  
  390.         HRESULT STDMETHODCALLTYPE CreatePixelShader(CONST DWORD* pFunction,IDirect3DPixelShader9** ppShader) {
  391.             *ppShader = new DummyD3DPixelShader(this, pFunction);
  392.             (*ppShader)->AddRef();
  393.             return S_OK;
  394.         }
  395.  
  396.         HRESULT STDMETHODCALLTYPE SetVertexShader(IDirect3DVertexShader9* pShader) { return S_OK; }
  397.         HRESULT STDMETHODCALLTYPE SetVertexShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount) { return S_OK; }
  398.         HRESULT STDMETHODCALLTYPE SetVertexShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount) { return S_OK; }
  399.         HRESULT STDMETHODCALLTYPE SetVertexShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT  BoolCount) { return S_OK; }
  400.  
  401.         HRESULT STDMETHODCALLTYPE SetPixelShader(IDirect3DPixelShader9* pShader) { return S_OK; }
  402.         HRESULT STDMETHODCALLTYPE SetPixelShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount) { return S_OK; }
  403.         HRESULT STDMETHODCALLTYPE SetPixelShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount) { return S_OK; }
  404.         HRESULT STDMETHODCALLTYPE SetPixelShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT  BoolCount) { return S_OK; }
  405.  
  406.         // We need to record these.
  407.         HRESULT STDMETHODCALLTYPE SetTexture(DWORD Stage,IDirect3DBaseTexture9* pTexture) {
  408.             if (pTexture && mRequiredCaps.MaxSimultaneousTextures <= Stage)
  409.                 mRequiredCaps.MaxSimultaneousTextures = Stage + 1;
  410.  
  411.             uint32 token = 0x30000000 + (Stage << 12);
  412.  
  413.             if (pTexture)
  414.                 token += static_cast<DummyD3DBaseTexture *>(pTexture)->GetId();
  415.  
  416.             mAccumulatedStates.push_back(token);
  417.             return S_OK;
  418.         }
  419.  
  420.         HRESULT STDMETHODCALLTYPE SetTextureStageState(DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) {
  421.             if ((Type == D3DTSS_COLOROP || Type == D3DTSS_ALPHAOP) && Value != D3DTOP_DISABLE) {
  422.                 if (mRequiredCaps.MaxTextureBlendStages <= Stage)
  423.                     mRequiredCaps.MaxTextureBlendStages = Stage + 1;
  424.  
  425.                 switch(Value) {
  426.                     case D3DTOP_ADD:                        mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_ADD; break;
  427.                     case D3DTOP_ADDSIGNED:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_ADDSIGNED; break;
  428.                     case D3DTOP_ADDSIGNED2X:                mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_ADDSIGNED2X; break;
  429.                     case D3DTOP_ADDSMOOTH:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_ADDSMOOTH; break;
  430.                     case D3DTOP_BLENDCURRENTALPHA:            mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_BLENDCURRENTALPHA; break;
  431.                     case D3DTOP_BLENDDIFFUSEALPHA:            mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_BLENDDIFFUSEALPHA; break;
  432.                     case D3DTOP_BLENDFACTORALPHA:            mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_BLENDFACTORALPHA; break;
  433.                     case D3DTOP_BLENDTEXTUREALPHA:            mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_BLENDTEXTUREALPHA; break;
  434.                     case D3DTOP_BLENDTEXTUREALPHAPM:        mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_BLENDTEXTUREALPHAPM; break;
  435.                     case D3DTOP_BUMPENVMAP:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_BUMPENVMAP; break;
  436.                     case D3DTOP_BUMPENVMAPLUMINANCE:        mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_BUMPENVMAPLUMINANCE; break;
  437.                     case D3DTOP_DISABLE:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_DISABLE; break;
  438.                     case D3DTOP_DOTPRODUCT3:                mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_DOTPRODUCT3; break;
  439.                     case D3DTOP_LERP:                        mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_LERP; break;
  440.                     case D3DTOP_MODULATE:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_MODULATE; break;
  441.                     case D3DTOP_MODULATE2X:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_MODULATE2X; break;
  442.                     case D3DTOP_MODULATE4X:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_MODULATE4X; break;
  443.                     case D3DTOP_MODULATEALPHA_ADDCOLOR:        mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR; break;
  444.                     case D3DTOP_MODULATECOLOR_ADDALPHA:        mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA; break;
  445.                     case D3DTOP_MODULATEINVALPHA_ADDCOLOR:    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR; break;
  446.                     case D3DTOP_MODULATEINVCOLOR_ADDALPHA:    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA; break;
  447.                     case D3DTOP_MULTIPLYADD:                mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_MULTIPLYADD; break;
  448.                     case D3DTOP_PREMODULATE:                mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_PREMODULATE; break;
  449.                     case D3DTOP_SELECTARG1:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_SELECTARG1; break;
  450.                     case D3DTOP_SELECTARG2:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_SELECTARG2; break;
  451.                     case D3DTOP_SUBTRACT:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_SUBTRACT; break;
  452.                 }
  453.             }
  454.  
  455.             uint32 token = 0x10000000 + (Stage << 24) + (Type << 12);
  456.  
  457.             if (Value < 0xFFF) {
  458.                 mAccumulatedStates.push_back(token + Value);
  459.             } else {
  460.                 mAccumulatedStates.push_back(token + 0xFFF);
  461.                 mAccumulatedStates.push_back(Value);
  462.             }
  463.             return S_OK;
  464.         }
  465.  
  466.         HRESULT STDMETHODCALLTYPE SetRenderState(D3DRENDERSTATETYPE State,DWORD Value) {
  467.             switch(State) {
  468.                 case D3DRS_BLENDOP:
  469.                     if (Value != D3DBLENDOP_ADD)
  470.                         mRequiredCaps.PrimitiveMiscCaps |= D3DPMISCCAPS_BLENDOP;
  471.                     break;
  472.  
  473.                 case D3DRS_SRCBLEND:
  474.                 case D3DRS_DESTBLEND:
  475.                     {
  476.                         DWORD blendCap = 0;
  477.  
  478.                         switch(Value) {
  479.                             case D3DBLEND_BLENDFACTOR:
  480.                                 blendCap = D3DPBLENDCAPS_BLENDFACTOR;
  481.                                 break;
  482.                             case D3DBLEND_BOTHINVSRCALPHA:
  483.                                 blendCap = D3DPBLENDCAPS_BOTHINVSRCALPHA;
  484.                                 break;
  485.                             case D3DBLEND_BOTHSRCALPHA:
  486.                                 blendCap = D3DPBLENDCAPS_BOTHSRCALPHA;
  487.                                 break;
  488.                             case D3DBLEND_DESTALPHA:
  489.                                 blendCap = D3DPBLENDCAPS_DESTALPHA;
  490.                                 break;
  491.                             case D3DBLEND_DESTCOLOR:
  492.                                 blendCap = D3DPBLENDCAPS_DESTCOLOR;
  493.                                 break;
  494.                             case D3DBLEND_INVDESTALPHA:
  495.                                 blendCap = D3DPBLENDCAPS_INVDESTALPHA;
  496.                                 break;
  497.                             case D3DBLEND_INVDESTCOLOR:
  498.                                 blendCap = D3DPBLENDCAPS_INVDESTCOLOR;
  499.                                 break;
  500.                             case D3DBLEND_INVSRCALPHA:
  501.                                 blendCap = D3DPBLENDCAPS_INVSRCALPHA;
  502.                                 break;
  503.                             case D3DBLEND_INVSRCCOLOR:
  504.                                 blendCap = D3DPBLENDCAPS_INVSRCCOLOR;
  505.                                 break;
  506.                             case D3DBLEND_ONE:
  507.                                 blendCap = D3DPBLENDCAPS_ONE;
  508.                                 break;
  509.                             case D3DBLEND_SRCALPHA:
  510.                                 blendCap = D3DPBLENDCAPS_SRCALPHA;
  511.                                 break;
  512.                             case D3DBLEND_SRCALPHASAT:
  513.                                 blendCap = D3DPBLENDCAPS_SRCALPHASAT;
  514.                                 break;
  515.                             case D3DBLEND_SRCCOLOR:
  516.                                 blendCap = D3DPBLENDCAPS_SRCCOLOR;
  517.                                 break;
  518.                             case D3DBLEND_ZERO:
  519.                                 blendCap = D3DPBLENDCAPS_ZERO;
  520.                                 break;
  521.                         }
  522.  
  523.                         if (State == D3DRS_SRCBLEND)
  524.                             mRequiredCaps.SrcBlendCaps |= blendCap;
  525.                         else
  526.                             mRequiredCaps.DestBlendCaps |= blendCap;
  527.                     }
  528.                     break;
  529.             }
  530.  
  531.             if (Value < 0xFFF) {
  532.                 mAccumulatedStates.push_back((State << 12) + Value);
  533.             } else {
  534.                 mAccumulatedStates.push_back((State << 12) + 0xFFF);
  535.                 mAccumulatedStates.push_back(Value);
  536.             }
  537.             return S_OK;
  538.         }
  539.  
  540.         HRESULT STDMETHODCALLTYPE SetSamplerState(DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD Value) {
  541.             uint32 token = 0x20000000 + (Sampler << 24) + (Type << 12);
  542.  
  543.             if (Value < 0xFFF) {
  544.                 mAccumulatedStates.push_back(token + Value);
  545.             } else {
  546.                 mAccumulatedStates.push_back(token + 0xFFF);
  547.                 mAccumulatedStates.push_back(Value);
  548.             }
  549.             return S_OK;
  550.         }
  551.  
  552.     public:
  553.         const uint32 *GetStates() const { return &mAccumulatedStates[0]; }
  554.         int GetStateCount() const { return (int)mAccumulatedStates.size(); }
  555.  
  556.         void ClearStates() { mAccumulatedStates.clear(); }
  557.  
  558.         const D3DCAPS9& GetRequiredCaps() const { return mRequiredCaps; }
  559.         void ClearRequiredCaps() {
  560.             memset(&mRequiredCaps, 0, sizeof mRequiredCaps);
  561.         }
  562.  
  563.     protected:
  564.         volatile LONG mRefCount;
  565.  
  566.         D3DCAPS9 mRequiredCaps;
  567.  
  568.         vdfastvector<uint32> mAccumulatedStates;
  569.     };
  570. }
  571.  
  572. namespace {
  573.     struct PassInfo {
  574.         int mVertexShaderIndex;
  575.         int mPixelShaderIndex;
  576.         int mStateStart;
  577.         int mStateEnd;
  578.         int mRenderTarget;
  579.         uint8 mViewportW;
  580.         uint8 mViewportH;
  581.         uint8 mBumpEnvScale;
  582.         bool mbClipPosition;
  583.         bool mbRTDoClear;
  584.         uint32 mRTClearColor;
  585.     };
  586.  
  587.     void DeleteShaderConstantTable(std::vector<uint32>& shader) {
  588.         LPCVOID data;
  589.         UINT size;
  590.         if (D3D_OK == D3DXFindShaderComment((const DWORD *)&shader[0], MAKEFOURCC('C', 'T', 'A', 'B'), &data, &size)) {
  591.             ptrdiff_t offset = (char *)data - (char *)&shader[0];
  592.  
  593.             VDASSERT(!(offset & 3));
  594.             VDASSERT(offset >= 8);
  595.  
  596.             // convert to dword offset
  597.             offset >>= 2;
  598.             size = (size + 3) >> 2;
  599.  
  600.             VDASSERT(offset + size <= shader.size());
  601.  
  602.             // erase comment token, fourcc, and comment data
  603.             shader.erase(shader.begin() + (offset - 2), shader.begin() + offset + size);
  604.         }
  605.     }
  606.  
  607.     void EmitShaderConstants(vdfastvector<uint32>& states, ID3DXConstantTable *pConstants, bool pixelShader) {
  608.         D3DXCONSTANTTABLE_DESC desc;
  609.         HRESULT hr;
  610.         hr = pConstants->GetDesc(&desc);
  611.         if (FAILED(hr)) {
  612.             printf("ID3DXConstantTable::GetDesc() failed, HRESULT=%08x\n", hr);
  613.             exit(20);
  614.         }
  615.  
  616.         D3DXCONSTANT_DESC descArray[16];
  617.         uint32 baseOffset = pixelShader ? 0x40000000 : 0x00000000;
  618.  
  619.         for(UINT i=0; i<desc.Constants; ++i) {
  620.             D3DXHANDLE hConstant = pConstants->GetConstant(NULL, i);
  621.             UINT count = 16;
  622.  
  623.             hr = pConstants->GetConstantDesc(hConstant, descArray, &count);
  624.             if (FAILED(hr)) {
  625.                 printf("ID3DXConstantTable::GetConstantDesc() failed, HRESULT=%08x\n", hr);
  626.                 exit(20);
  627.             }
  628.  
  629.             for(UINT dc=0; dc<count; ++dc) {
  630.                 const D3DXCONSTANT_DESC& desc = descArray[dc];
  631.  
  632.                 switch(desc.RegisterSet) {
  633.                     case D3DXRS_BOOL:
  634.                     case D3DXRS_INT4:
  635.                     case D3DXRS_FLOAT4:
  636.                         {
  637.                             for(int index=0; index<sizeof(kParameterNames)/sizeof(kParameterNames[0]); ++index) {
  638.                                 if (!strcmp(kParameterNames[index], desc.Name)) {
  639.                                     switch(desc.RegisterSet) {
  640.                                     case D3DXRS_BOOL:
  641.                                         states.push_back(baseOffset + 0x80000000 + (desc.RegisterIndex << 12) + index);
  642.                                         break;
  643.                                     case D3DXRS_INT4:
  644.                                         states.push_back(baseOffset + 0x90000000 + (desc.RegisterIndex << 12) + index);
  645.                                         break;
  646.                                     case D3DXRS_FLOAT4:
  647.                                         states.push_back(baseOffset + 0xA0000000 + (desc.RegisterIndex << 12) + index);
  648.                                         break;
  649.                                     }
  650.                                     goto param_found;
  651.                                 }
  652.                             }
  653.  
  654.                             printf("Error: Unknown constant: %s\n", desc.Name);
  655.                             exit(10);
  656.                         }
  657. param_found:
  658.                         break;
  659.                     case D3DXRS_SAMPLER:
  660.                         if (!strncmp(desc.Name, "vd_", 3)) {
  661.                             for(int index=0; index<sizeof(kTextureNames)/sizeof(kTextureNames[0]); ++index) {
  662.                                 if (!strcmp(kTextureNames[index], desc.Name)) {
  663.                                     UINT samplerIndex = pConstants->GetSamplerIndex(hConstant);
  664.                                     states.push_back(0x30000000 + (samplerIndex << 24) + index + 1);
  665.                                     goto texture_found;
  666.                                 }
  667.                             }
  668.  
  669.                             printf("Error: Unknown texture: %s\n", desc.Name);
  670.                             exit(10);
  671.                         }
  672. texture_found:
  673.                         break;
  674.                 }
  675.             }
  676.         }
  677.     }
  678. }
  679.  
  680. void tool_fxc(const vdfastvector<const char *>& args, const vdfastvector<const char *>& switches, bool amd64) {
  681.     if (args.size() != 2) {
  682.         puts("usage: asuka fxc source.fx target.cpp");
  683.         exit(5);
  684.     }
  685.  
  686.     const char *filename = args[0];
  687.  
  688.     printf("Asuka: Compiling effect file (Direct3D): %s -> %s.\n", filename, args[1]);
  689.  
  690.     vdrefptr<DummyD3DDevice> pDevice(new DummyD3DDevice);
  691.     vdrefptr<DummyD3DBaseTexture> pSrcTexture(new DummyD3DBaseTexture(pDevice, 1));
  692.     vdrefptr<DummyD3DBaseTexture> pSrc2aTexture(new DummyD3DBaseTexture(pDevice, 2));
  693.     vdrefptr<DummyD3DBaseTexture> pSrc2bTexture(new DummyD3DBaseTexture(pDevice, 3));
  694.     vdrefptr<DummyD3DBaseTexture> pTempTexture(new DummyD3DBaseTexture(pDevice, 4));
  695.     vdrefptr<DummyD3DBaseTexture> pTemp2Texture(new DummyD3DBaseTexture(pDevice, 5));
  696.     vdrefptr<DummyD3DBaseTexture> pCubicTexture(new DummyD3DBaseTexture(pDevice, 6));
  697.     vdrefptr<DummyD3DBaseTexture> pHEvenOddTexture(new DummyD3DBaseTexture(pDevice, 7));
  698.     vdrefptr<DummyD3DBaseTexture> pInterpHTexture(new DummyD3DBaseTexture(pDevice, 8));
  699.     vdrefptr<DummyD3DBaseTexture> pInterpVTexture(new DummyD3DBaseTexture(pDevice, 9));
  700.  
  701.     vdrefptr<ID3DXEffect> pEffect;
  702.     vdrefptr<ID3DXBuffer> pErrors;
  703.  
  704.     DWORD flags = D3DXSHADER_NO_PRESHADER;
  705.  
  706. #ifdef D3DXSHADER_USE_LEGACY_D3DX9_31_DLL
  707.     // The V32 compiler seems to be broken in that it thinks "point" and "linear" are
  708.     // keywords.
  709.     flags |= D3DXSHADER_USE_LEGACY_D3DX9_31_DLL;
  710. #endif
  711.  
  712.     HRESULT hr = D3DXCreateEffectFromFile(pDevice, filename, NULL, NULL, flags, NULL, ~pEffect, ~pErrors);
  713.  
  714.     if (FAILED(hr)) {
  715.         printf("Effect compilation failed for \"%s\"\n", filename);
  716.  
  717.         if (pErrors)
  718.             puts((const char *)pErrors->GetBufferPointer());
  719.  
  720.         exit(10);
  721.     }
  722.  
  723.     pErrors.clear();
  724.  
  725. #if 0
  726.     vdrefptr<ID3DXBuffer> pDisasm;
  727.     hr = D3DXDisassembleEffect(pEffect, FALSE, ~pDisasm);
  728.  
  729.     if (SUCCEEDED(hr))
  730.         puts((const char *)pDisasm->GetBufferPointer());
  731.  
  732.     pDisasm.clear();
  733. #endif
  734.  
  735.     // dump the effect
  736.     D3DXEFFECT_DESC desc;
  737.     pEffect->GetDesc(&desc);
  738.  
  739.     pEffect->SetTexture("vd_srctexture", pSrcTexture);
  740.     pEffect->SetTexture("vd_src2atexture", pSrc2aTexture);
  741.     pEffect->SetTexture("vd_src2btexture", pSrc2bTexture);
  742.     pEffect->SetTexture("vd_temptexture", pTempTexture);
  743.     pEffect->SetTexture("vd_temp2texture", pTemp2Texture);
  744.     pEffect->SetTexture("vd_cubictexture", pCubicTexture);
  745.     pEffect->SetTexture("vd_hevenoddtexture", pHEvenOddTexture);
  746.     pEffect->SetTexture("vd_interphtexture", pInterpHTexture);
  747.     pEffect->SetTexture("vd_interpvtexture", pInterpVTexture);
  748.  
  749.     FILE *f = fopen(args[1], "w");
  750.     if (!f) {
  751.         printf("Couldn't open %s for write\n", args[1]);
  752.         exit(10);
  753.     }
  754.  
  755.     fprintf(f, "// Effect data auto-generated by Asuka from %s. DO NOT EDIT!\n", VDFileSplitPath(filename));
  756.  
  757.     fprintf(f, "\n");
  758.     fprintf(f, "struct PassInfo {\n");
  759.     fprintf(f, "\tint mVertexShaderIndex;\n");
  760.     fprintf(f, "\tint mPixelShaderIndex;\n");
  761.     fprintf(f, "\tint mStateStart;\n");
  762.     fprintf(f, "\tint mStateEnd;\n");
  763.     fprintf(f, "\tint mRenderTarget;\n");
  764.     fprintf(f, "\tuint8 mViewportW;\n");
  765.     fprintf(f, "\tuint8 mViewportH;\n");
  766.     fprintf(f, "\tuint8 mBumpEnvScale;\n");
  767.     fprintf(f, "\tbool mbClipPosition;\n");
  768.     fprintf(f, "\tbool mbRTDoClear;\n");
  769.     fprintf(f, "\tuint32 mRTClearColor;\n");
  770.     fprintf(f, "};\n");
  771.  
  772.     fprintf(f, "\n");
  773.     fprintf(f, "struct TechniqueInfo {\n");
  774.     fprintf(f, "\tconst PassInfo *mpPasses;\n");
  775.     fprintf(f, "\tuint32 mPassCount;\n");
  776.     fprintf(f, "\tuint32 mPSVersionRequired;\n");
  777.     fprintf(f, "\tuint32 mVSVersionRequired;\n");
  778.     fprintf(f, "\tuint32 mPrimitiveMiscCaps;\n");
  779.     fprintf(f, "\tuint32 mMaxSimultaneousTextures;\n");
  780.     fprintf(f, "\tuint32 mMaxTextureBlendStages;\n");
  781.     fprintf(f, "\tuint32 mSrcBlendCaps;\n");
  782.     fprintf(f, "\tuint32 mDestBlendCaps;\n");
  783.     fprintf(f, "\tuint32 mTextureOpCaps;\n");
  784.     fprintf(f, "\tfloat mPixelShader1xMaxValue;\n");
  785.     fprintf(f, "};\n");
  786.  
  787.     fprintf(f, "\n");
  788.     fprintf(f, "struct EffectInfo {\n");
  789.     fprintf(f, "\tconst uint32 *mpShaderData;\n");
  790.     fprintf(f, "\tconst uint32 *mVertexShaderOffsets;\n");
  791.     fprintf(f, "\tuint32 mVertexShaderCount;\n");
  792.     fprintf(f, "\tconst uint32 *mPixelShaderOffsets;\n");
  793.     fprintf(f, "\tuint32 mPixelShaderCount;\n");
  794.     fprintf(f, "};\n");
  795.  
  796.     std::list<std::vector<uint32> > mVertexShaders;
  797.     std::list<std::vector<uint32> > mPixelShaders;
  798.     vdfastvector<uint32> mStates;
  799.  
  800.     pDevice->ClearStates();
  801.  
  802.     for(int technique=0; technique<(int)desc.Techniques; ++technique) {
  803.         D3DXHANDLE hTechnique = pEffect->GetTechnique(technique);
  804.         D3DXTECHNIQUE_DESC techDesc;
  805.  
  806.         pEffect->GetTechniqueDesc(hTechnique, &techDesc);
  807.         pEffect->SetTechnique(hTechnique);
  808.  
  809.         pDevice->ClearRequiredCaps();
  810.  
  811.         UINT passCount = 0;
  812.         if (FAILED(pEffect->Begin(&passCount, D3DXFX_DONOTSAVESTATE))) {
  813.             puts("Begin failed!");
  814.             exit(20);
  815.         }
  816.  
  817.         vdfastvector<PassInfo> mPasses;
  818.         uint32 maxVSVersion = 0;
  819.         uint32 maxPSVersion = 0;
  820.  
  821.         for(int pass=0; pass<(int)passCount; ++pass) {
  822.             D3DXHANDLE hPass = pEffect->GetPass(hTechnique, pass);
  823.             D3DXPASS_DESC passDesc;
  824.  
  825.             pEffect->GetPassDesc(hPass, &passDesc);
  826.  
  827.             int stateStart = mStates.size();
  828.  
  829.             int psIndex = -1;
  830.             if (passDesc.pPixelShaderFunction) {
  831.                 std::vector<uint32> ps(passDesc.pPixelShaderFunction, passDesc.pPixelShaderFunction + (D3DXGetShaderSize(passDesc.pPixelShaderFunction) >> 2));
  832.  
  833.                 DeleteShaderConstantTable(ps);
  834.  
  835.                 // slow... fix if perf bottleneck
  836.                 int psIndex2 = 0;
  837.                 for(std::list<std::vector<uint32> >::const_iterator it(mPixelShaders.begin()), itEnd(mPixelShaders.end()); it!=itEnd; ++it, ++psIndex2) {
  838.                     if (*it == ps) {
  839.                         psIndex = psIndex2;
  840.                         break;
  841.                     }
  842.                 }
  843.  
  844.                 if (psIndex < 0) {
  845.                     mPixelShaders.push_back(std::vector<uint32>());
  846.                     mPixelShaders.back().swap(ps);
  847.                     psIndex = mPixelShaders.size() - 1;
  848.                 }
  849.  
  850.                 vdrefptr<ID3DXConstantTable> pConstantTable;
  851.                 if (D3D_OK == D3DXGetShaderConstantTable(passDesc.pPixelShaderFunction, ~pConstantTable))
  852.                     EmitShaderConstants(mStates, pConstantTable, true);
  853.  
  854.                 uint32 psVersion = passDesc.pPixelShaderFunction[0] & 0xffff;
  855.                 if (psVersion > maxPSVersion)
  856.                     maxPSVersion = psVersion;
  857.             }
  858.  
  859.             int vsIndex = -1;
  860.             if (passDesc.pVertexShaderFunction) {
  861.                 std::vector<uint32> vs(passDesc.pVertexShaderFunction, passDesc.pVertexShaderFunction + (D3DXGetShaderSize(passDesc.pVertexShaderFunction) >> 2));
  862.  
  863.                 DeleteShaderConstantTable(vs);
  864.  
  865.                 // slow... fix if perf bottleneck
  866.                 int vsIndex2 = 0;
  867.                 for(std::list<std::vector<uint32> >::const_iterator it(mVertexShaders.begin()), itEnd(mVertexShaders.end()); it!=itEnd; ++it, ++vsIndex2) {
  868.                     if (*it == vs) {
  869.                         vsIndex = vsIndex2;
  870.                         break;
  871.                     }
  872.                 }
  873.  
  874.                 if (vsIndex < 0) {
  875.                     mVertexShaders.push_back(std::vector<uint32>());
  876.                     mVertexShaders.back().swap(vs);
  877.                     vsIndex = mVertexShaders.size() - 1;
  878.                 }
  879.  
  880.                 vdrefptr<ID3DXConstantTable> pConstantTable;
  881.                 if (D3D_OK == D3DXGetShaderConstantTable(passDesc.pVertexShaderFunction, ~pConstantTable))
  882.                     EmitShaderConstants(mStates, pConstantTable, false);
  883.  
  884.                 uint32 vsVersion = passDesc.pVertexShaderFunction[0] & 0xffff;
  885.                 if (vsVersion > maxVSVersion)
  886.                     maxVSVersion = vsVersion;
  887.             }
  888.  
  889.             hr = pEffect->BeginPass(pass);
  890.             if (FAILED(hr)) {
  891.                 puts("BeginPass failed!");
  892.                 exit(20);
  893.             }
  894.  
  895.             int stateCount = pDevice->GetStateCount();
  896.             if (stateCount > 0) {
  897.                 const uint32 *p = pDevice->GetStates();
  898.                 mStates.insert(mStates.end(), p, p+stateCount);
  899.             }
  900.             int stateEnd = mStates.size();
  901.  
  902.             pDevice->ClearStates();
  903.  
  904.             PassInfo pi;
  905.             pi.mVertexShaderIndex = vsIndex;
  906.             pi.mPixelShaderIndex = psIndex;
  907.             pi.mStateStart = stateStart;
  908.             pi.mStateEnd = stateEnd;
  909.             pi.mRenderTarget = -1;
  910.             pi.mViewportW = 0;
  911.             pi.mViewportH = 0;
  912.  
  913.             // force first pass to always default to main RT
  914.             if (!pass) {
  915.                 pi.mRenderTarget = 0;
  916.                 pi.mViewportW = 2;
  917.                 pi.mViewportH = 2;
  918.             }
  919.  
  920.             D3DXHANDLE hRTAnno = pEffect->GetAnnotationByName(hPass, "vd_target");
  921.             if (hRTAnno) {
  922.                 LPCSTR s;
  923.                 if (SUCCEEDED(pEffect->GetString(hRTAnno, &s))) {
  924.                     if (!*s) {
  925.                         pi.mRenderTarget = 0;
  926.  
  927.                         // main RT defaults to out,out instead of full,full
  928.                         pi.mViewportW = 2;
  929.                         pi.mViewportH = 2;
  930.                     } else if (!strcmp(s, "temp"))
  931.                         pi.mRenderTarget = 1;
  932.                     else if (!strcmp(s, "temp2"))
  933.                         pi.mRenderTarget = 2;
  934.                     else {
  935.                         printf("Error: Unknown render target: %s\n", s);
  936.                         exit(10);
  937.                     }
  938.                 }
  939.             }
  940.  
  941.             D3DXHANDLE hVPAnno = pEffect->GetAnnotationByName(hPass, "vd_viewport");
  942.             if (hVPAnno) {
  943.                 LPCSTR s;
  944.                 if (SUCCEEDED(pEffect->GetString(hVPAnno, &s))) {
  945.                     bool valid = true;
  946.  
  947.                     const char *brk = strchr(s, ',');
  948.                     if (!brk)
  949.                         valid = false;
  950.  
  951.                     if (valid) {
  952.                         std::string hvp(s, brk);
  953.  
  954.                         if (hvp == "src")
  955.                             pi.mViewportW = 1;
  956.                         else if (hvp == "out")
  957.                             pi.mViewportW = 2;
  958.                         else if (hvp != "full")
  959.                             valid = false;
  960.                     }
  961.  
  962.                     if (valid) {
  963.                         ++brk;
  964.                         while(*brk == ' ')
  965.                             ++brk;
  966.  
  967.                         if (!strcmp(brk, "src"))
  968.                             pi.mViewportH = 1;
  969.                         else if (!strcmp(brk, "out"))
  970.                             pi.mViewportH = 2;
  971.                         else if (strcmp(brk, "full"))
  972.                             valid = false;
  973.                     }
  974.  
  975.                     if (!valid) {
  976.                         printf("Error: Invalid viewport annotation: %s\n", s);
  977.                         exit(10);
  978.                     }
  979.                 }
  980.             }
  981.  
  982.             pi.mbClipPosition = false;
  983.             D3DXHANDLE hClipPosAnno = pEffect->GetAnnotationByName(hPass, "vd_clippos");
  984.             if (hClipPosAnno) {
  985.                 BOOL b;
  986.                 if (SUCCEEDED(pEffect->GetBool(hClipPosAnno, &b))) {
  987.                     if (b)
  988.                         pi.mbClipPosition = true;
  989.                 }
  990.             }
  991.  
  992.             pi.mbRTDoClear = false;
  993.             pi.mRTClearColor = 0;
  994.             D3DXHANDLE hRTClearAnno = pEffect->GetAnnotationByName(hPass, "vd_clear");
  995.             if (hRTClearAnno) {
  996.                 D3DXVECTOR4 v;
  997.                 if (SUCCEEDED(pEffect->GetVector(hRTClearAnno, &v))) {
  998.                     pi.mRTClearColor    = (VDClampedRoundFixedToUint8Fast(v.x) << 16)
  999.                                         + (VDClampedRoundFixedToUint8Fast(v.y) <<  8)
  1000.                                         + (VDClampedRoundFixedToUint8Fast(v.z) <<  0)
  1001.                                         + (VDClampedRoundFixedToUint8Fast(v.w) << 24);
  1002.  
  1003.                     pi.mbRTDoClear = true;
  1004.                 }
  1005.             }
  1006.  
  1007.             pi.mBumpEnvScale = 0;
  1008.             D3DXHANDLE hBESAnno = pEffect->GetAnnotationByName(hPass, "vd_bumpenvscale");
  1009.             if (hBESAnno) {
  1010.                 LPCSTR s;
  1011.                 if (SUCCEEDED(pEffect->GetString(hBESAnno, &s))) {
  1012.                     for(int i=0; i<sizeof(kParameterNames)/sizeof(kParameterNames[0]); ++i) {
  1013.                         if (!strcmp(s, kParameterNames[i])) {
  1014.                             pi.mBumpEnvScale = i+1;
  1015.                             break;
  1016.                         }
  1017.                     }
  1018.  
  1019.                     if (!pi.mBumpEnvScale) {
  1020.                         printf("Error: Unknown source for bump-map environment matrix scale: %s\n", s);
  1021.                         exit(10);
  1022.                     }
  1023.                 }
  1024.             }
  1025.  
  1026.             mPasses.push_back(pi);
  1027.  
  1028.             pEffect->EndPass();
  1029.         }
  1030.  
  1031.         pEffect->End();
  1032.  
  1033.         // emit passes
  1034.         fprintf(f, "static const PassInfo g_technique_%s_passes[]={\n", techDesc.Name);
  1035.         for(int i=0; i<(int)passCount; ++i) {
  1036.             const PassInfo& pi = mPasses[i];
  1037.             fprintf(f, "\t{ %d, %d, %d, %d, %d, %d, %d, %d, %s, %s, 0x%08x },\n"
  1038.                 , pi.mVertexShaderIndex
  1039.                 , pi.mPixelShaderIndex
  1040.                 , pi.mStateStart
  1041.                 , pi.mStateEnd
  1042.                 , pi.mRenderTarget
  1043.                 , pi.mViewportW
  1044.                 , pi.mViewportH
  1045.                 , pi.mBumpEnvScale
  1046.                 , pi.mbClipPosition ? "true" : "false"
  1047.                 , pi.mbRTDoClear ? "true" : "false"
  1048.                 , pi.mRTClearColor);
  1049.         }
  1050.         fprintf(f, "};\n");
  1051.  
  1052.         const D3DCAPS9& caps = pDevice->GetRequiredCaps();
  1053.  
  1054.         fprintf(f, "static const TechniqueInfo g_technique_%s={\n", techDesc.Name);
  1055.         fprintf(f, "\tg_technique_%s_passes, %d,\n", techDesc.Name, passCount);
  1056.         fprintf(f, "\tD3DPS_VERSION(%d,%d),\n", maxPSVersion >> 8, maxPSVersion & 255);
  1057.         fprintf(f, "\tD3DVS_VERSION(%d,%d),\n", maxVSVersion >> 8, maxVSVersion & 255);
  1058.         fprintf(f, "\t0x%08x,\n", caps.PrimitiveMiscCaps);
  1059.         fprintf(f, "\t0x%08x,\n", caps.MaxSimultaneousTextures);
  1060.         fprintf(f, "\t0x%08x,\n", caps.MaxTextureBlendStages);
  1061.         fprintf(f, "\t0x%08x,\n", caps.SrcBlendCaps);
  1062.         fprintf(f, "\t0x%08x,\n", caps.DestBlendCaps);
  1063.         fprintf(f, "\t0x%08x,\n", caps.TextureOpCaps);
  1064.         fprintf(f, "\t%d.f,\n", maxPSVersion >= 0x0104 ? 2 : maxPSVersion >= 0x0101 ? 1 : 0);
  1065.         fprintf(f, "};\n");
  1066.     }
  1067.  
  1068.     // Emit state array.
  1069.     const int stateCount = mStates.size();
  1070.     if (stateCount > 0) {
  1071.         fprintf(f, "static const uint32 g_states[]={\n");
  1072.         for(int i=0; i<stateCount; i+=8) {
  1073.             fprintf(f, "\t");
  1074.             for(int j=i; j<i+8 && j<stateCount; ++j) {
  1075.                 fprintf(f, "0x%08x,", mStates[j]);
  1076.             }
  1077.             fprintf(f, "\n");
  1078.         }
  1079.         fprintf(f, "};\n");
  1080.     }
  1081.  
  1082.     // Emit all vertex and pixel shaders
  1083.     std::list<std::vector<uint32> >::iterator it, itEnd;
  1084.  
  1085.     std::vector<uint32> mShaderData;
  1086.     vdfastvector<int> mVertexShaderOffsets;
  1087.     vdfastvector<int> mPixelShaderOffsets;
  1088.  
  1089.     for(it=mVertexShaders.begin(), itEnd=mVertexShaders.end(); it!=itEnd; ++it) {
  1090.         mVertexShaderOffsets.push_back(mShaderData.size());
  1091.         mShaderData.insert(mShaderData.end(), it->begin(), it->end());
  1092.     }
  1093.     mVertexShaderOffsets.push_back(mShaderData.size());
  1094.  
  1095.     for(it=mPixelShaders.begin(), itEnd=mPixelShaders.end(); it!=itEnd; ++it) {
  1096.         mPixelShaderOffsets.push_back(mShaderData.size());
  1097.         mShaderData.insert(mShaderData.end(), it->begin(), it->end());
  1098.     }
  1099.     mPixelShaderOffsets.push_back(mShaderData.size());
  1100.  
  1101.     fprintf(f, "static const uint32 g_shaderData[]={\n");
  1102.     for(int i=0, count=mShaderData.size(); i<count; i+=8) {
  1103.         fprintf(f, "\t");
  1104.         for(int j=i; j<i+8 && j<count; ++j) {
  1105.             fprintf(f, "0x%08x,", mShaderData[j]);
  1106.         }
  1107.         fprintf(f, "\n");
  1108.     }
  1109.     fprintf(f, "};\n");
  1110.  
  1111.     // output shader list
  1112.     fprintf(f, "static const uint32 g_shaderOffsets[]={\n");
  1113.     fprintf(f, "\t");
  1114.     for(int i=0; i<(int)mVertexShaderOffsets.size(); ++i)
  1115.         fprintf(f, "%d,", mVertexShaderOffsets[i]);
  1116.     fprintf(f, "\n");
  1117.     fprintf(f, "\t");
  1118.     for(int i=0; i<(int)mPixelShaderOffsets.size(); ++i)
  1119.         fprintf(f, "%d,", mPixelShaderOffsets[i]);
  1120.     fprintf(f, "\n");
  1121.     fprintf(f, "};\n");
  1122.  
  1123.     // output effect data
  1124.     fprintf(f, "static const EffectInfo g_effect={\n");
  1125.         fprintf(f, "\tg_shaderData,\n");
  1126.         fprintf(f, "\tg_shaderOffsets+0, %d,\n", mVertexShaderOffsets.size() - 1);
  1127.         fprintf(f, "\tg_shaderOffsets+%d, %d\n", mVertexShaderOffsets.size(), mPixelShaderOffsets.size() - 1);
  1128.     fprintf(f, "};\n");
  1129.     fclose(f);
  1130.  
  1131.     printf("Asuka: %d techniques, %d shader bytes, %d state bytes.\n", desc.Techniques, mShaderData.size()*4, mStates.size()*4);
  1132.     printf("Asuka: Compilation was successful.\n");
  1133. }
  1134.